1
La brecha de rendimiento: ¿Por qué extender NumPy?
AI018Lesson 5
00:00

Aunque NumPy está construido sobre C, ciertos algoritmos intensivos en cálculo alcanzan una pared de vectorización. Esto ocurre cuando la latencia inherente de la naturaleza dinámica de Python supera los beneficios de la abstracción de alto nivel.

1. El impuesto del intérprete y el empaquetado

Cada iteración en un bucle estándar de Python implica comprobación dinámica de tipos y contaje de referencias. Incluso al usar escalares de NumPy, el "empaquetado" de datos brutos de C en objetos de Python crea un cuello de botella enorme para funciones como $\text{logit}(p) = \log(p/(1-p))$. Manejar casos límite en C es mucho más rápido:

>>> logit(0) -> -inf
>>> logit(1) -> inf
>>> logit(2) -> nan
>>> logit(-2) -> nan

2. Aumento de tamaño de matrices intermedias

Las expresiones puras de NumPy crean búferes de memoria temporales para cada operación secundaria. Ampliar mediante la API de C permite Fusión de kernels, donde la transformación logit se calcula en un solo paso sin sobrecarga adicional de memoria.

3. Dependencias espaciales

Operaciones que involucran patrones de acceso a vecinos, como el stencil 2D:

$$B(I, J) = A(I, J) + (A(I-1, J) + A(I+1, J) + A(I, J-1) + A(I, J+1)) \cdot 0.5D0 + (A(I-1, J-1) + A(I-1, J+1) + A(I+1, J-1) + A(I+1, J+1)) \cdot 0.25D0$$

son difíciles de expresar de forma eficiente mediante rebanadas sin copias redundantes de memoria. Las extensiones en C permiten el uso de aritmética de punteros directa y alineada con la caché.

main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>